#ifndef BALISE
#define BALISE
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include "Noeud.h"
#include "Attribut.h"
using namespace std;

/**
	Classe repésentant une balise XML
*/
class Balise : public Noeud {
	private:
		/** tag de la balise */
		string nom;

		/** espace de nom de la balise. Chaine vide si pas d'espace de nom */
		string espaceNom;

		/** indique si la balise est simple (sinon double)*/
		bool simple;

		//TODO: transformer en list de noeud
		/** liste des fils de la balise */
		list<Noeud*> fils;

		/** liste des attributs de la balise */
		vector<Attribut*> attributs;

	public:
		/** constructeur */
 		Balise(string unNom, bool baliseSimple); 

		/** destructeur */
		~Balise();

		/** renvoi une copie profonde de la balise */
		Noeud* getCopieProfonde();

 		/** renvoi le nom de la balise */
		string getNom(); 

		/** renvoi l'espace de nom de la balise */
		string getEspaceNom();

		/** retourne vrai si la balise a un espace de nom, faux sinon */
		bool hasEspaceNom();

		string getNomAvecEspace();

		/** renvoi vrai si la balise est une balise simple, faux sinon*/
		bool estSimple();

		/** herité de Noeud. Retourne toujours vrai.*/
		//bool estBalise(); //deprecated

		NoeudType getType();

		const list<Noeud*>& getFils();

		/** renvoi la liste des fils étant des balises (retire les textes) */
		list<Balise*> getListeBaliseFils();

		bool findFils(Noeud* unNoeud, list<Noeud*>::iterator &position);

		/** ajoute une fils à la liste des fils de la balise */
		void ajouterFils(Noeud* monfils);

		/** insère un noeud après le noeud noeudPrécedent */
		bool ajouterFilsApres(Noeud* nouveauFils, Noeud* noeudPrecedent);

		/** ajoute une liste de fils à la balise */
		void ajouterListeFils(list<Noeud*>* uneListeFils);

		bool ajouterListFilsApres(list<Noeud*>* uneListeFils, Noeud* noeudPrecedent);

		/**
			retire  un noeud de la liste des fils
			renvoi vrai si le fils a été trouvé et retiré avec succes, faux sinon 
		*/
		bool detacherFils(Noeud *unFils);

		/** ajoute un attribut à la liste des attributs de la balise */
		void ajouterAttribut(Attribut* unAttribut);

		/** ajoute tous les attributs du vecteur à la liste d'attributs de la balise */
		void ajouterAttributs(vector<Attribut*>* uneListeAttributs);

		/** retourne un tableau ce string contenant les nom des attributs de la balise */
		vector<string> getNomsAttributs();

		/** retourne le premier attribut nomé unNom. Retourne null si aucun attribut avec ce nom n'est trouvé*/
		Attribut* getAttributWithName(string unNom);

		/** retourne la liste des attibuts de la balise */ 
		const vector<Attribut*>& getAttributs();

		/** 
			renvoi un string représentant la version XML de cette balise. 
			Les attributs et les fils sont également renvoyés 
		*/
		string toString(int nbTab);

		/** retourne une expression texte à comparer à une regex pour valider le XML */
		string getRegexExp();

		/** retourne une expression texte à comparer à une regex pour valider le XML */
		string getFilsExpForRegex();
};

#endif
